#include <string>
#include "RecursoDeAlmacenamiento.h"


void EstrategiaRecursoEscrituraDirecta::crear(RecursoDeAlmacenamiento* recurso, enumAlmacenamiento estAlmacenamiento, enumIndice estIndice, int longitudBuffer, int longitudBloqueIndice, int longitudBloque){
	//creacion del buffer de lectura
	Buffer newBuffer(longitudBuffer);
	recurso->setBuffer(&newBuffer);
	
	//creacion del archivo
	if(estAlmacenamiento == TEXTO){ ;
			EstrategiaAlmacenamientoTexto a;
			Archivo newFile(recurso->getNombreArchivo(), &a, longitudBloque);
			recurso->setArchivo(&newFile);
			this->crearIndice(recurso, &a, estIndice, longitudBloqueIndice, longitudBloque);
	} else if(estAlmacenamiento == REGISTROS){ ;
			EstrategiaAlmacenamientoRegistros a;
			Archivo newFile(recurso->getNombreArchivo(), &a, longitudBloque);
			recurso->setArchivo(&newFile);
			this->crearIndice(recurso, &a, estIndice, longitudBloqueIndice, longitudBloque);
	} else if(estAlmacenamiento == BLOQUES){ ;
			EstrategiaAlmacenamientoBloques a;
			Archivo newFile(recurso->getNombreArchivo(), &a, longitudBloque);
			recurso->setArchivo(&newFile);
			this->crearIndice(recurso, &a, estIndice, longitudBloqueIndice, longitudBloque);
	} else { ;
			EstrategiaAlmacenamientoRegistros a;
			Archivo newFile(recurso->getNombreArchivo(), &a, longitudBloque);
			recurso->setArchivo(&newFile);
			this->crearIndice(recurso, &a, estIndice, longitudBloqueIndice, longitudBloque);
	}
}

void EstrategiaRecursoEscrituraDirecta::crearIndice(RecursoDeAlmacenamiento* recurso, EstrategiaAlmacenamiento* eAlmacenamiento, enumIndice estIndice, int longitudBloqueIndice, int longitudBloque){
	if(estIndice == HASH_EXTENSIBLE){ ;
			IndexadoHashExtensible i;
			Indice newIndex(recurso->getNombreArchivo(), &i, eAlmacenamiento, longitudBloque, longitudBloqueIndice);
			recurso->setIndice(&newIndex);
	} else if(estIndice == BSHARP){ ;
			IndexadoBSharp i;
			Indice newIndex(recurso->getNombreArchivo(), &i, eAlmacenamiento, longitudBloque, longitudBloqueIndice);
			recurso->setIndice(&newIndex);
	} else if(estIndice == NO_INDEXADO){ ;
			NoIndexado i;
			Indice newIndex(recurso->getNombreArchivo(), &i, eAlmacenamiento, longitudBloque, longitudBloqueIndice);
			recurso->setIndice(&newIndex);
	} else { ;
			NoIndexado i;
			Indice newIndex(recurso->getNombreArchivo(), &i, eAlmacenamiento, longitudBloque, longitudBloqueIndice);
			recurso->setIndice(&newIndex);
	}
}

void EstrategiaRecursoEscrituraDirecta::almacenar(RecursoDeAlmacenamiento* recurso, Registro registro){
	recurso->getBuffer()->almacenar(registro);
	int direccion = recurso->getArchivo()->almacenar(registro);
	recurso->getIndice()->indexar(registro.getValoresClaves(), direccion);
}

void EstrategiaRecursoEscrituraDirecta::cerrar(RecursoDeAlmacenamiento* recurso){
	recurso->getArchivo()->cerrar();
	recurso->getBuffer()->cerrar();
}


void EstrategiaRecursoEscrituraDirecta::modificar(RecursoDeAlmacenamiento* recurso, Registro registro, int offset){
	recurso->getArchivo()->modificar(registro, offset);
	recurso->getBuffer()->modificar(registro, offset);
}

Registro EstrategiaRecursoEscrituraDirecta::buscar(RecursoDeAlmacenamiento* recurso, int offset, list<string> claves){
	Registro r;
	try{
		//busca en el buffer. Si no lo encuentra, busca en el archivo.
		r = recurso->getArchivo()->recuperar(offset, claves);
	} catch(int){
		return recurso->getArchivo()->recuperar(offset, claves);
	}
	return r;
}

void EstrategiaRecursoEscrituraDirecta::borrar(RecursoDeAlmacenamiento* recurso, int offset, list<string> claves){
	recurso->getArchivo()->borrar(offset);
	recurso->getBuffer()->borrar(offset);
}
